using UniversalAdminSystem.Application.Common.Interfaces;
using UniversalAdminSystem.Application.PermissionManagement.DTOs;
using UniversalAdminSystem.Application.PermissionManagement.Interfaces;
using UniversalAdminSystem.Domian.PermissionManagement.Aggregate;
using UniversalAdminSystem.Domian.PermissionManagement.Interfaces;
using UniversalAdminSystem.Domian.PermissionManagement.IRepository;
using UniversalAdminSystem.Domian.PermissionManagement.ValueObjects;

namespace UniversalAdminSystem.Application.PermissionManagement.Services;

/// <summary>
/// 权限管理应用服务实现
/// 提供权限的创建、查询、分配等业务操作的具体实现
/// </summary>
public class PermissionManagementAppService : IPermissionManagementAppService
{
    private readonly IUnitOfWork _unitOfWork;
    private readonly IPermissionRepository _permissionRepository;
    private readonly IRoleRepository _roleRepository;
    private readonly IAssignPermissionDomainService _assignPermissionDomainService;

    public PermissionManagementAppService(
        IUnitOfWork unitOfWork,
        IPermissionRepository permissionRepository,
        IRoleRepository roleRepository,
        IAssignPermissionDomainService assignPermissionDomainService
    )
    {
        _unitOfWork = unitOfWork;
        _permissionRepository = permissionRepository;
        _roleRepository = roleRepository;
        _assignPermissionDomainService = assignPermissionDomainService;
    }

    /// <summary>
    /// 为角色分配权限
    /// </summary>
    public async Task AssignPermissionToRoleAsync(AssignPermissionDto assignDto)
    {
        try
        {
            await _unitOfWork.BeginTransactionAsync();
            var permission = await _permissionRepository.GetByCodeAsync((PermissionCode)assignDto.PermissionCode)
                ?? throw new KeyNotFoundException("未找到对应的权限");
            var role = await _roleRepository.GetByGuidAsync(assignDto.RoleId)
                ?? throw new KeyNotFoundException("未找到对应的角色");
            var state = _assignPermissionDomainService.AssignPermission(permission, role);
            if (state)
            {
                await _roleRepository.Update(role);
                
            }
            await _unitOfWork.CommitAsync();
        }
        catch (KeyNotFoundException)
        {
            await _unitOfWork.RollbackAsync();
            throw;
        }
    }

    /// <summary>
    /// 创建新权限
    /// </summary>
    public async Task<PermissionDto> CreatePermissionAsync(PermissionCreateDto createDto)
    {
        try
        {
            if (!Enum.IsDefined(typeof(PermissionAction), createDto.ActionValue))
            {
                throw new InvalidOperationException($"无效的操作类型值: {createDto.ActionValue}");
            }
            PermissionAction enumValue = (PermissionAction)createDto.ActionValue;
            // 检查权限代码是否已存在
            var existingPermission = await _permissionRepository.GetByCodeAsync(PermissionCode.Create($"{createDto.Resource}:{enumValue}"));
            if (existingPermission != null)
            {
                throw new InvalidOperationException($"权限代码 '{createDto.Resource}:{enumValue}' 已存在，无法创建重复权限");
            }

            // 开启事务
            await _unitOfWork.BeginTransactionAsync();

            // 创建权限并保存
            var permission = Permission.CreateStandardPermission(
                createDto.Name,
                createDto.Resource,
                createDto.ActionValue,
                createDto.Description
            );

            try
            {
                var savedPermission = await _permissionRepository.AddAsync(permission);
                await _unitOfWork.CommitAsync();
                return new PermissionDto(
                    savedPermission.Name,
                    savedPermission.Code,
                    savedPermission.Description!
                );
            }
            catch (System.Exception ex)
            {
                throw new InvalidOperationException(ex.Message);
            }
        }
        catch (System.Exception ex)
        {
            await _unitOfWork.RollbackAsync();
            throw new InvalidOperationException(ex.Message);
        }
    }

    /// <summary>
    /// 获取所有权限列表
    /// </summary>
    public async Task<IEnumerable<PermissionDto>> GetAllPermissionAsync()
    {
        var permissions = await _permissionRepository.GetAllAsync();
        var permissionList = permissions.Select(p => new PermissionDto(p.Name, p.Code, p.Description!));
        return permissionList;
    }

    /// <summary>
    /// 删除权限
    /// </summary>
    public async Task RemovePermissionAsync(Guid permissionId)
    {
        try
        {
            await _unitOfWork.BeginTransactionAsync();
            await _permissionRepository.RemoveAsync(permissionId);
            await _unitOfWork.CommitAsync();
        }
        catch (System.Exception ex)
        {
            await _unitOfWork.RollbackAsync();
            throw new System.Exception(ex.Message);
        }
    }
}
